/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c) 2002, GeoVISTA Center
 * Licensed under Simplified BSD License
 * This library is developed and distributed for free usage,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * You can redistribute and/or modify it under the terms of the
 * Simplified BSD License
 *
 *
 *
 *
 *
 *
 *
 * @original author: jin Chen 
 * @author: jin Chen 
 * @date: Nov 12, 2008$
 * @version: 1.0
 */


package edu.psu.geovista.app.vit.pub.utils;

import edu.psu.geovista.app.visualclassifier.classify.v2.DefaultESVisualClassifier;
import edu.psu.geovista.classification.CategoryItf;
import edu.psu.geovista.classification.ClassificationResultItf;
import edu.psu.geovista.classification.setting.ClassifySetting1D;
import edu.psu.geovista.common.utils.ArrayUtils;
import edu.psu.geovista.data.model.AppDataModel;
import org.apache.commons.math.stat.descriptive.rank.Max;
import org.apache.commons.math.stat.descriptive.rank.Min;

import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.util.List;

public class VitUtils {

   public static List convertArrayToList(Color[] array){
         ArrayList  list=new ArrayList();
        for (int i=0;i<array.length ;i++){
            list.add(array[i]);
        }
         return list;
    }
     public static double[] convert2DoubleArray(Collection v){
        Object[] os=v.toArray();
        double[] result=new double[os.length ];
        for (int i=0;i<os.length ;i++){
            Number o=(Number) os[i];
            if(o!=null)
                result[i]=o.doubleValue() ;//floatValue(o);
            else
                result[i]=Double.NaN ;

        }
        return result;
    }
    public static double[] getMinMax(double[] values){
        double[] v = getCopied(values);
    /*Arrays.sort(v);
    return new double[]{ v[0],v[v.length -1]};*/
        double min = new Min().evaluate(v); //values
        double max = new Max().evaluate(v);//values
        return new double[]{min,max};
    }
    private static double[] getCopied(double[] values) {
        double[] v=new double[values.length ]; // use  a copy of the data to avoid change to original data
        System.arraycopy(values,0,v,0,values.length );
        return v;
    }
     public static String[] convert2StringArrayNoNull(Collection list){
        if(list==null){
            throw new NullPointerException("Can't convert null list");
        }
        String[] ss=new String[list.size() ];
        int i=0;
        for (Iterator iterator = list.iterator(); iterator.hasNext();) {
            Object o = iterator.next();
            String s = (o==null)?"":o.toString() ; // 
            ss[i++]=s;
        }
        return ss;
    }
     public static HashSet convertArrayToSet(int[] array){
        HashSet set=new HashSet();
        for (int i=0;i<array.length ;i++){
            Integer e=new Integer(array[i]);
            set.add(e);
        }
        return set;
    }
     public static Object[] convert2Array(Collection collection){
        if(collection ==null){
            throw new NullPointerException("Can't convert null set");
        }
        Object[] ss=new Object[collection.size() ];
        int i=0;
        for (Iterator iterator = collection.iterator(); iterator.hasNext();) {
            Object s =  iterator.next();
            ss[i++]=s;
        }
        return ss;
    }
     public  static Vector convert2Vector(Object[] anArray) {
        if (anArray == null) {
            return null;
        }
        Vector v = new Vector(anArray.length);
        for (int i=0; i < anArray.length; i++) {
            v.add(anArray[i]);
        }
        return v;
    }
    public static int[] convert2IntArray(Collection<Integer> data){
        int[] intA;
        if (data.size() <=0){
            intA=new int[0];
        }
        else{
           intA=new int[data.size() ];
            Object[] tmp=data.toArray() ;
            for (int i=0;i<intA.length ;i++){
                intA[i]=((Integer)tmp[i]).intValue() ;
            }
        }
          return intA;
    }
    public static List convertArrayToList(String [] array){
        ArrayList  list=new ArrayList();
        for (int i=0;i<array.length ;i++){
            //String  s=array[i];
            list.add(array[i]);
        }
        return list;
    }
    public static int showDialog(Component parent,Object gui,String title,Object[] buttons){
        if(buttons==null||buttons.length ==0)
            buttons=new Object[]{"OK","Cancel"};
        int value= JOptionPane.showOptionDialog(parent, gui,title,
                JOptionPane.YES_NO_OPTION,
                JOptionPane.PLAIN_MESSAGE ,
                null,
                buttons,
                buttons[0]);
        return value;
    }
     public static int[] add(int[] a1, int[] a2){
        int len1 = a1.length;
        int len2 = a2.length;
        int[] result=new int[len1+len2];
        System.arraycopy(a1,0,result,0,len1);
        System.arraycopy(a2,0,result,len1 ,len2);
        return result;
    }

    /**
     * generate divergent colors
     * @param model
     * @param ctgcount
     * @return
     */
    public static Color[][] generateDDcolors(AppDataModel model, int ctgcount){
        System.out.println("generateDDcolors");
       // model.simplePrint();
        ////todo temp remove the release dependency on Visual Classifier. Need bring it backup after refactory VC
        DefaultESVisualClassifier vc=new DefaultESVisualClassifier();
        int rowCount = model.getRowCount();
        int columnCount = model.getColumnCount();
        Color[][] colors=new Color[rowCount][columnCount];
        try {
            //int ctgcount=11;//must <= 11
            vc.setDataModel(model);
            vc.setUniColorScheme("div","PuOr",ctgcount);
            ClassifySetting1D set=new ClassifySetting1D();
            String classifymethod="Quantiles";

            set.setClassifier(classifymethod);
            set.setNumOfCategory(ctgcount);
            set.setBoundaries(null); //set.setBound(null);

            String[] colnames = model.getColumnNames();
            for (int col =0;col <colnames.length ;col++){
                set.setVariableName(colnames[col]);
                vc.classify(set);
                Color[] acolumncolor = vc.getDataColors();
                
                ArrayUtils.print(acolumncolor);
                for (int row =0;row <rowCount;row++){
                    colors[row][col]=acolumncolor[row];
                }

            }
            System.out.println("");
            print(vc) ;
            System.out.println("");
        } catch (Exception e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        return colors;
        //return null;

    }

    public static void print(DefaultESVisualClassifier vc){
        System.out.println("print classification -->");
         ClassificationResultItf clsr = vc.getClassifyResult();
        //double[] boundaryX = clsr.getBoundaryX();
       // ArrayUtils.print(boundaryX);
        CategoryItf[] ctgs = clsr.getCategories();
        for (int i=0;i<ctgs.length ;i++){
            CategoryItf ctg = ctgs[i];
            System.out.println(" category: "+ ctg.getRange().toString());
            System.out.println(" data indexs "+ctg.getMemberIds()+"   "+ ctg.getVisualInfo().getColor());

        }
         System.out.println("print classification --");
    }
    public static void showWaitCursor (Container container,Cursor csr) {
        if (container == null) return ;
        if(csr==null){
            csr=new Cursor(Cursor.WAIT_CURSOR);
        }

        if (SwingUtilities.isEventDispatchThread ()) {
            container.setCursor (csr);//Utilities.createProgressCursor (contentPane));
        } else {
            SwingUtilities.invokeLater (new CursorR (container,csr));//Utilities.createProgressCursor (contentPane)));
        }
        //SwingUtilities.getWindowAncestor()
        //SwingUtilities2.


    }

    public static void showNormalCursor (Container container) {
        if (container == null) return ;
        if (SwingUtilities.isEventDispatchThread ()) {
            container.setCursor (null); // 
        } else {
            SwingUtilities.invokeLater (new CursorR (container, null));
        }
    }
    private static class CursorR implements Runnable {
           private Container contentPane;
           private Cursor c;

           private CursorR (Container cont, Cursor c) {
               contentPane = cont;
               this.c = c;
           }

           public void run () {
               contentPane.setCursor (c);
           }
       }
    public static String[] getSplitFileName(String filename){
        String choppedFilename; //without extension
        String ext;
        int dotPlace = filename.lastIndexOf ( '.' );
        if ( dotPlace >= 0 ){
            // possibly empty
            choppedFilename = filename.substring( 0, dotPlace );
            // possibly empty
            ext = filename.substring( dotPlace + 1 );
        }
        else{
            // was no extension
            choppedFilename = filename;
            ext = "";
        }
        return new String[]{choppedFilename, ext};
    }
     public static String getFileExtension(String filename){
        return getSplitFileName(filename)[1];
    }
    
}
